namespace Domotica.Windows.Controls
{
    using Microsoft.VisualBasic;
    using Domotica.Windows.Input;
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Diagnostics;
    using System.Reflection;
    using System.Runtime.CompilerServices;
    using System.Windows;
    using System.Windows.Automation.Peers;
    using System.Windows.Documents;
    using System.Windows.Ink;
    using System.Windows.Input;

    public class SignExtender : AdornerDecorator
    {
        private SignAdorner _Adorner;
        private bool _InitGestureRecognitionDone;
        private StylusPointCollection _StylusPoints;
        private GestureRecognizer recognizer;

        public event SignEventHandler SignEvent;

        public SignExtender()
        {
            this._StylusPoints = null;
            this._InitGestureRecognitionDone = false;
            this.recognizer = new GestureRecognizer();
        }

        internal void DoPreviewMouseUp(MouseButtonEventArgs e)
        {
            if (e.StylusDevice == null)
            {
                if (this.StylusPoints == null)
                {
                    this._StylusPoints = new StylusPointCollection();
                }
                Point pt = e.GetPosition(this);
                StylusPoint stylusPoint = new StylusPoint(pt.X, pt.Y);
                this.StylusPoints.Add(stylusPoint);
                StrokeCollection strokes = new StrokeCollection();
                strokes.Add(new Stroke(this.StylusPoints));
                if (this.recognizer.IsRecognizerAvailable)
                {
                    ReadOnlyCollection<GestureRecognitionResult> gestureResults = this.recognizer.Recognize(strokes);
                    if ((gestureResults.Count > 0) && (gestureResults[0].RecognitionConfidence <= RecognitionConfidence.Intermediate))
                    {
                        e.Handled = this.DoRaiseCommand((SignAction) gestureResults[0].ApplicationGesture, this._StylusPoints);
                    }
                }
                this._StylusPoints = null;
                strokes.Clear();
                this.InvalidateAdornerVisual();
            }
        }

        private bool DoRaiseCommand(SignAction signAction, StylusPointCollection stylusPoints)
        {
            if (signAction == SignAction.None)
            {
                return false;
            }
            SignEventArgs sea = new SignEventArgs(SignDevice.Current, 0, signAction, stylusPoints);
            sea.RoutedEvent = SignDevice.SignEvent;
            typeof(CommandManager).InvokeMember("TranslateInput", BindingFlags.InvokeMethod | BindingFlags.NonPublic | BindingFlags.Static, null, typeof(CommandManager), new object[] { this, sea });
            if (!sea.Handled)
            {
                this.DoSignEvent(sea);
            }
            if (AutomationPeer.ListenerExists(AutomationEvents.InvokePatternOnInvoked))
            {
                AutomationPeer peer = UIElementAutomationPeer.CreatePeerForElement(this);
                if (peer != null)
                {
                    peer.RaiseAutomationEvent(AutomationEvents.InvokePatternOnInvoked);
                }
            }
            return sea.Handled;
        }

        private void DoSignEvent(SignEventArgs e)
        {
            SignEventHandler handler = this.SignEvent;
            if (handler != null)
            {
                handler(this, e);
            }
        }

        private void InitGestureRecognition()
        {
            if (!this._InitGestureRecognitionDone)
            {
                List<ApplicationGesture> l = new List<ApplicationGesture>();
                foreach (InputBinding b in InputBindings)
                {
                    if (b is SignBinding)
                    {
                        SignBinding sb = (SignBinding) b;
                        l.Add((ApplicationGesture) sb.SignAction);
                    }
                }
            }
        }

        private void InvalidateAdornerVisual()
        {
            if (this._Adorner!=null)
            {
                this._Adorner.InvalidateVisual();
            }
        }

        protected override void OnInitialized(EventArgs e)
        {
            base.OnInitialized(e);
            this._Adorner = new SignAdorner(this, this);
            this.AdornerLayer.Add(this._Adorner);
        }

        protected override void OnPreviewMouseDown(MouseButtonEventArgs e)
        {
            base.OnPreviewMouseDown(e);
            this.InitGestureRecognition();
            this._StylusPoints = new StylusPointCollection();
            Point pt = e.GetPosition(this);
            StylusPoint stylusPoint = new StylusPoint(pt.X, pt.Y);
            this.StylusPoints.Add(stylusPoint);
            this.InvalidateAdornerVisual();
        }

        protected override void OnPreviewMouseMove(MouseEventArgs e)
        {
            base.OnPreviewMouseMove(e);
            if ((e.LeftButton != MouseButtonState.Released) && (this.StylusPoints != null))
            {
                Point pt = e.GetPosition(this);
                StylusPoint stylusPoint = new StylusPoint(pt.X, pt.Y);
                this.StylusPoints.Add(stylusPoint);
                this.InvalidateAdornerVisual();
            }
        }

        protected override void OnPreviewMouseUp(MouseButtonEventArgs e)
        {
            base.OnPreviewMouseUp(e);
            this.DoPreviewMouseUp(e);
        }

        internal StylusPointCollection StylusPoints
        {
            get
            {
                return this._StylusPoints;
            }
        }
    }
}

